import { message } from "antd"
import axios from "axios"
import { hideLoading, showLoading } from "./load"
import storage from "./storage"

// 数据返回的接口
// 定义请求响应参数，不含data
interface Result {
  code: number
  msg: string
}

// 请求响应参数，包含data
export interface ResultData<T> extends Result {
  data: T
}

const instance = axios.create({
  baseURL: import.meta.env.VITE_BASE_API,
  timeout: 10000,
  timeoutErrorMessage: "网络请求超时，请稍后再试",
  withCredentials: true
})

instance.interceptors.request.use(
  config => {
    showLoading()
    const token = storage.get("token")
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`
    }
    const params = new URLSearchParams(location.search)
    location.href = params.get("callback") || "/"
    return config
  },
  error => {
    Promise.reject(error)
  }
)

instance.interceptors.response.use(
  response => {
    hideLoading()
    const data = response.data
    if (data.code !== 200) {
      message.error(data.msg)
      return Promise.reject(new Error(data.msg))
    }
    return data.data
  },
  error => {
    hideLoading()
    if (error.message === "Network Error") {
      message.error("网络请求错误，请稍后再试")
    } else if (error.code === 401) {
      message.error("登录状态已过期，请重新登录")
      localStorage.removeItem("token")
      window.location.href = "/login"
    }
    return Promise.reject(error)
  }
)

export default {
  get<T>(url: string, params?: object): Promise<T> {
    return instance.get(url, { params })
  },
  post<T>(url: string, params?: object): Promise<T> {
    return instance.post(url, params)
  },
  put<T>(url: string, params?: object): Promise<T> {
    return instance.put(url, params)
  },
  delete<T>(url: string, params?: object): Promise<T> {
    return instance.delete(url, { params })
  },
  patch<T>(url: string, params?: object): Promise<T> {
    return instance.patch(url, params)
  },
  head<T>(url: string, params?: object): Promise<T> {
    return instance.head(url, { params })
  },
  options<T>(url: string, params?: object): Promise<T> {
    return instance.options(url, { params })
  },
  upload<T>(url: string, params?: object): Promise<T> {
    return instance.post(url, params)
  },
  download(url: string, params?: object): Promise<Blob> {
    return instance
      .get(url, { params, responseType: "blob" })
      .then(response => response.data)
  }
}
